/**
 * Copyright (c) 2011-2019, James Zhan 詹波 (jfinal@126.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jfinal.server.undertow;

import java.io.File;
import io.undertow.server.handlers.resource.ClassPathResourceManager;
import io.undertow.server.handlers.resource.FileResourceManager;
import io.undertow.server.handlers.resource.ResourceManager;

/**
 * 1：FileResourceManager 支持在普通目录下去加载 css、js 等 web 静态资源
 * 
 * 2：ClassPathResourceManager 支持在 class path 下与 jar 包内加载 css、js
 *    等 web 静态资源
 * 
 * 3：ClassPathResourceManager 第二个参数不能省略，也不能为 ""，否则可以在浏览器地址栏直接访问
 *    class path、jar 中的所有资源，包括配置文件，下面的用法极其危险:
 *       new ClassPathResourceManager(getClassLoader()));
 * 
 * 4：在需要用到 ClassPathResourceManager 时为给定一个参数，例如：
 *       new ClassPathResourceManager(getClassLoader(), "webapp"));
 *       
 *    上例给定 webapp 参数，undertow 将可以从 class path、jar 包内的
 *    webapp 之下去寻找资源
 * 
 */
public class ResourceManagerKit {
	
	public static ResourceManager buildResourceManager(String resourcePath, ClassLoader classLoader) {
		/**
		 * 提升配置 undertow.resourcePath 时的用户体验，可以仅配置开发时的 path，
		 * 可以免去配置生产环境的 webapp
		 * 例如：undertow.resourcePath=src/main/resources/static
		 */
		if ( ! resourcePath.contains("webapp")) {
			resourcePath = resourcePath + ",webapp";
		}
		
		CompositeResourceManager ret = new CompositeResourceManager();
		String resourcePathArray[] = resourcePath.split(",");
		/**
		 * 开发时使用 eclipse 启动将会正确添加 FileResourceManager
		 * 执行 java -jar xxx.jar 命令时，当前目录下面如果存在 path 目录将会被添加
		 * 
		 * 经测试 eclipse 启动项目的当前目录值为 APP_BASE
		 */
		for (String path : resourcePathArray) {
			path = path.trim();
			if (new File(path).isDirectory()) {
		        ret.add(new FileResourceManager(new File(path)));
		    }
		}
		
		if (UndertowKit.isDeployMode()) {
			forDeployMode(classLoader, ret);
		}
		
		return ret;
	}
	
	/**
	 * 部署模式下需要额外搜索目录用于 FileResourceManager
	 * 额外添加 webapp、static 为前缀的 ClassPathResourceManager 到最末尾
	 */
	private static void forDeployMode(ClassLoader classLoader, CompositeResourceManager ret) {
		/**
		 * 如果前方没有 FileResourceManager 被添加成功，搜索可能存在的 webapp 目录
		 */
		if (ret.isEmpty()) {
			String path = PathKitExt.getLocationPath();
			if (path.endsWith(File.separatorChar + "lib")) {
				path = path.substring(0, path.lastIndexOf(File.separatorChar));
			}
			path = new File(path + File.separator + "webapp").getAbsolutePath();
			
			if (new File(path).isDirectory()) {
				ret.add(new FileResourceManager(new File(path)));
			}
		}
		
		/**
		 * 额外添加一个指向 webapp 的 ClassPathResourceManager
		 * 该 webapp 内部是 css、js 等这类 web 资源，该目录将被打包
		 * 到 jar 之中去
		 * 
		 * 如果有人习惯使用使用 static 作为目录，还需要开启最下方的代码
		 */
		ret.add(new ClassPathResourceManager(classLoader, "webapp"));
		
		// ret.add(new ClassPathResourceManager(classLoader, "static"));
	}
}





